﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation.Runspaces;
using System.Management.Automation;
using System.IO;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Runtime.Serialization.Formatters.Binary;

namespace PSWebLogic
{
    /*
     * This class include all the PowerShell related methods. Because v2.0 is around the corner, and i want to make
     * the change from v1.0 to v2.0 as easy as I can, the web application don't use any of the PowerShell objects
     */
    public static class PSUtil
    {
        public static bool IsPSV2()
        {
            List<PSCommand> commands = new List<PSCommand>();
            commands.Add(new PSCommand() { CommandText = "$host.version.tostring()" });
            string version = ExecuteComand(commands, GetNewRunspaceObject(null, null));
            if (version.Trim()=="2.0")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public static object GetNewRunspaceObject(List<string> SnapInsToAdd, List<string> SnapInsToRemove)
        {
            RunspaceConfiguration config = RunspaceConfiguration.Create();

            PSSnapInException warning;
            if (SnapInsToAdd != null)
            {
                foreach (var snapin in SnapInsToAdd)
                {
                    config.AddPSSnapIn(snapin, out warning);

                }
            }
            if (SnapInsToRemove != null)
            {
                foreach (var snapin in SnapInsToRemove)
                {
                    config.RemovePSSnapIn(snapin, out warning);
                }
            }
            Runspace runspace = RunspaceFactory.CreateRunspace(config);
            
            return (object)runspace;
        }
        public static string ExecuteScript(string path, object runspaceobj)
        {
            return ExecuteComand(new List<PSCommand>() { new PSCommand() { CommandText = File.ReadAllText(path) } }, runspaceobj);
        }
        public static string ExecuteComand(List<PSCommand> commands, object runspaceobj)
        {
            Runspace runspace = GetWorkableRunspace(runspaceobj);
            Collection<PSObject> results;
            StringBuilder sb = new StringBuilder();
            if (runspace.RunspaceStateInfo.State == RunspaceState.BeforeOpen)
            {
                runspace.Open();
            }

            Pipeline pipeline = runspace.CreatePipeline();
            foreach (var item in commands)
            {
                pipeline.Commands.AddScript(item.CommandText);
            }
            pipeline.Commands.Add("Out-String"); //To make sure we'll be able to display the results
            try
            {
                results = pipeline.Invoke();
            }
            catch (CommandNotFoundException ex)
            {

                return string.Format("The command {0} does not exists.", ex.CommandName);
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            foreach (PSObject item in results)
            {
                sb.AppendLine(item.ToString());
            }
            return sb.ToString();
        }

        private static Runspace GetWorkableRunspace(object runspaceobj)
        {
            return (Runspace)runspaceobj;
        }
        public static void CloseRunspace(object runspaceobj)
        {
            ((Runspace)runspaceobj).Close();
        }
       
    }
}
